#include "Log.h"

NetWork::Log::Log()
: LogFileOutPutPath("./log.txt"), OutPutStream(LogFileOutPutPath, std::ios_base::app), EndOfLife(false)
{
    //避免阻塞
    FutureToLogFile = std::async(std::launch::async, [this](){
        this->AsyncToLogFile();
    });
}

NetWork::Log::~Log()
{    
    EndOfLife = true;
    FutureToLogFile.get();

    {
        //避免 FutureToLogFile 死锁
        std::lock_guard<std::mutex> lock(LogMutex);
        OutPutStream.close();
    }
}

void NetWork::Log::AsyncToLogFile()
{
    while (!EndOfLife) {
        std::this_thread::sleep_for(std::chrono::milliseconds(500));

        std::lock_guard<std::mutex> lock(LogMutex);
        if (Logs.empty())
            continue;

        OutPutStream << Logs.front() << std::endl;
        Logs.pop();
    }
}

void NetWork::Log::SetLogFileOutPutPath(const std::string &path)
{
    std::lock_guard<std::mutex> lock(LogMutex);
    OutPutStream.close();

    LogFileOutPutPath = path;

    std::filesystem::path p(path);
    if (!std::filesystem::exists(p.parent_path()))
        std::filesystem::create_directories(p.parent_path());

    OutPutStream.open(LogFileOutPutPath, std::ios_base::app);
}

NetWork::Log &NetWork::Log::Instance()
{
    static Log log;
    return log;
}
